home *** CD-ROM | disk | FTP | other *** search
- /*
- * Magic Media Lab Colorbars, from the Media Lab letterhead,
- * with some animation tricks. c.f. License.m for an example of use.
- */
-
- /*
- Copyright (c) 1991, 1992 by the MIT Media Laboratory
-
- This software is distributed by Michael Hawley of the MIT Media Laboratory.
- We hope it will be useful to you.
-
- Permission to use, copy, or modify this software for educational
- and research purposes only and without fee is hereby granted
- provided this notice appears on all copies, and provided you send
- us your improvements. Any other use of this software, in original
- or modified form, in whole or in part, requires specific permission
- from MIT. This software shall not be used, rewritten, or adapted
- for use in a commercial product without first obtaining appropriate
- licenses from MIT. MIT makes no representations about the suitability
- of this software for any purpose: it is provided "as is" without any
- warranty and any risk, damage, or liability incurred through your use
- of this software is yours alone.
-
- Michael Hawley
- MIT Media Laboratory
- 20 Ames Street,
- Cambridge, MA 02139
- mike@media-lab.mit.edu
- */
- #import "ColorBars.h"
- #import <dpsclient/wraps.h>
-
- @implementation ColorBars
-
- extern usleep(), random(), bcopy();
-
- #define N 8
-
- static float pct[N] = { .0790, .1535, .0564, .2279, .0745, .2596, .1083, .0406};
- static NXColor color[N];
-
- static void
- initColors(){
- int i = 0;
- #define C(r,g,b) color[i++] = NXConvertRGBToColor(r./256., g./256., b./256.);
- C(77,17,93)
- C(0,85,0)
- C(255,255,255)
- C(210,0,0)
- C(255,90,0)
- C(0,0,151)
- C(255,248,0)
- C(85,85,85)
- }
-
- - initFrame:(NXRect *)r {
- [super initFrame:r];
- backgroundColor = NX_COLORWHITE;
- delay = .25;
- initColors();
- return self;
- }
-
- void
- drawColors(c,R) NXColor *c; NXRect R; {
- int i;
- NXCoord w = R.size.width;
- NXRect r;
-
- r = R;
- r.size.width = w * pct[0];
-
- for (i=0; i<N; i++, r.size.width = w * pct[i]){
- NXSetColor(c[i]);
- NXRectFill(&r);
- r.origin.x += r.size.width;
- }
- }
-
- - drawColors:(NXColor *)c{
- drawColors(c,bounds);
- return self;
- }
-
- - (int)running { return running; }
-
- static NXColor
- fade(i,n,c1,c2)
- int i, n;
- NXColor c1, c2;
- /* return a color that's i/n of the way from c1->c2 in RGB */
- {
- float r1, g1, b1, r2, g2, b2;
- float p = (float)(i)/(float)(n-1);
- NXConvertColorToRGB(c1,&r1,&g1,&b1);
- NXConvertColorToRGB(c2,&r2,&g2,&b2);
- #define mix(a,b) (a-p*(a-b))
- r1 = mix(r1,r2); g1 = mix(g1,g2); b1 = mix(b1,b2);
- c1 = NXConvertRGBToColor(r1,g1,b1);
- return c1;
- }
-
- - fill:(NXColor)c {
- NXSetColor(c);
- NXRectFill(&bounds);
- return self;
- }
-
- - stop {
- running = 0;
- return self;
- }
-
- - (NXColor)backgroundColor { return backgroundColor; }
- - setBackgroundColor:(NXColor)c {
- backgroundColor = c;
- return self;
- }
-
- void
- swabScramble(n) int n[N]; {
- int k=0,r,t[N] = {0,1,2,3,4,5,6,7};
- #define pick(t,n) t[r=random()%n]
- #define skip(t,n) { int i,j=0; for (i=0;i<N;i++){ t[j] = t[i]; if (t[j] != n) j++; } }
- for (k=0;k<N;k++) n[k] = -1;
- k = 0;
-
- skip(t,k);
- n[k] = pick(t,7);
- skip(t,n[k]);
- n[n[k]] = k;
- while (n[k] != -1 && k < N) k++;
-
- skip(t,k);
- n[k] = pick(t,5);
- skip(t,n[k]);
- n[n[k]] = k;
- while (n[k] != -1 && k < N) k++;
-
- skip(t,k);
- n[k] = pick(t,3);
- skip(t,n[k]);
- n[n[k]] = k;
- while (n[k] != -1 && k < N) k++;
-
- skip(t,k);
- n[k] = pick(t,1);
- skip(t,n[k]);
- n[n[k]] = k;
- while (n[k] != -1 && k < N) k++;
- }
-
- void
- swabStep(DPSTimedEntry te, double timeNow, id self)
- /*
- * Interpolate between pairs of segments
- */
- {
- static int i = 0, f = 0;
- int j;
- static NXColor pc[N], cc[N];
- NXColor c[N];
- #define M 48
-
- if (i==0){ /* pick random pairs of colors */
- int n[8];
- if (f==0){
- f = 1;
- for (j=0;j<N;j++){
- pc[j] = [self backgroundColor];
- cc[j] = color[j];
- }
- } else {
- if (f%3 == 0){
- for (j=0;j<N;j++) cc[j] = color[j];
- } else {
- swabScramble(n);
- for (j=0;j<N;j++) cc[j] = pc[n[j]];
- }
- }
- }
-
- for (j=0;j<N;j++) c[j] = fade(i,M,pc[j],cc[j]);
- [self lockFocus];
- [self drawColors:c];
- i++;
- if (i==M || ![self running]){
- i = 0;
- if (![self running] && te) DPSRemoveTimedEntry(te);
- for (j=0;j<N;j++) pc[j] = cc[j];
- f++;
- }
- [self unlockFocus];
- [[self window] flushWindow]; NXPing();
- }
-
- void
- fadeStep(DPSTimedEntry te, double timeNow, id self) {
- static int i = 0;
- int j;
- NXColor c[N];
- #undef M
- #define M 64
- for (j=0;j<N;j++) c[j] = fade(i,M,[self backgroundColor],color[j]);
- [self lockFocus];
- [self drawColors:c];
- i++;
- if (i==M || ![self running]){
- i = 0;
- if (te) DPSRemoveTimedEntry(te);
- [self stop];
- }
- [self unlockFocus];
- [[self window] flushWindow]; NXPing();
- }
-
- - fadeOn {
- running = 1;
- while (running) fadeStep(0,0.,self), usleep(2500);
- return self;
- }
-
- void
- scramble(n) int *n; {
- int i, k, l, random();
- for (i=0; i<N; i++) n[i] = i;
- for (i=0; i<N; i++){
- k = random()%N;
- l = n[k];
- n[k] = n[i];
- n[i] = l;
- }
- }
-
- void
- scrambleStep(DPSTimedEntry te, double timeNow, id self) {
- static int skip = 0;
- int cn[N], j, random();
- NXColor c[N];
-
- if (skip > 0) { skip--; return; }
- [self lockFocus];
- if (random()%8 == 3){
- [self drawColors:color];
- skip = 3;
- } else {
- scramble(cn);
- for (j=0;j<N;j++) c[j] = color[cn[j]];
- [self drawColors:c];
- if (![self running]){
- DPSRemoveTimedEntry(te);
- [self stop];
- }
- }
- [self unlockFocus];
- [[self window] flushWindow]; NXPing();
- }
-
- - winkOff {
- NXRect r, a, b;
- r = a = b = bounds;
- drawColors(color,bounds); [window flushWindow]; NXPing();
- NXSetColor(backgroundColor);
- a.size.height = b.size.height = 1;
- a.origin.y = r.origin.y + r.size.height;
- while (a.origin.y > b.origin.y){
- NXRectFill(&a); NXRectFill(&b);
- a.origin.y -= 1;
- b.origin.y += 1;
- usleep(30000);
- [window flushWindow]; NXPing();
- }
- a.origin.y += 1;
- b.origin.y -= 1;
- r = b; r.size.height = a.origin.y - b.origin.y;
- while (r.size.width > 2){
- NXSetColor(backgroundColor); NXRectFill(&r);
- r.origin.x += 2; r.size.width -= 4;
- drawColors(color,r); [window flushWindow]; NXPing();
- }
- r.size.width = 1;
- NXSetColor(NXConvertRGBToColor(.05,.05,.05)); NXRectFill(&r);
- [window flushWindow]; NXPing();
- usleep(1000000);
- NXSetColor(backgroundColor); NXRectFill(&r);
- [window flushWindow]; NXPing();
- usleep(300000);
- return self;
- }
-
- - setDrawstyle:(int)n {
- style = n;
- return [self display];
- }
-
- - animate:(void (*)())f{
- if (!running)
- running++, DPSAddTimedEntry(0.025, f, self,100);
- return self;
- }
-
- - animate:(void (*)())f :(float)t{
- if (!running)
- running++, DPSAddTimedEntry(t, f, self,100);
- return self;
- }
-
- - drawSelf:(const NXRect *)rects :(int)n {
- switch (style){
- case PLAIN: return [self drawColors:color];
- case FADE: return [self animate:fadeStep];
- case SWAB: return [self animate:swabStep];
- case SCRAMBLE: return [self animate:scrambleStep:delay];
- case FSCRAMBLE: [self fadeOn];
- usleep(1000000);
- return [self animate:scrambleStep:delay];
- case CLEAR: return [self fill:backgroundColor];
- case WINKOFF: return [self winkOff];
- }
- return self;
- }
-
- @end
-